package com.jackstraw.jack_base.rules.service.impl;

import com.jackstraw.jack_base.datasource.common.aspect.annotation.DataSourceNameCut;
import com.jackstraw.jack_base.datasource.common.entity.enums.DataSourceTypeEnum;
import com.jackstraw.jack_base.datasource.mybatis.base.service.impl.MyBatisServiceImpl;
import com.jackstraw.jack_base.rules.dao.database.RuleGroupDao;
import com.jackstraw.jack_base.rules.entity.bo.RelationSargBo;
import com.jackstraw.jack_base.rules.entity.bo.RuleBo;
import com.jackstraw.jack_base.rules.entity.bo.RuleGroupBo;
import com.jackstraw.jack_base.rules.entity.enums.ResultEnum;
import com.jackstraw.jack_base.rules.entity.mapstruct.RuleGroupMapstruct;
import com.jackstraw.jack_base.rules.entity.po.RuleGroupKeyPo;
import com.jackstraw.jack_base.rules.entity.po.RuleGroupPo;
import com.jackstraw.jack_base.rules.entity.po.RuleGroupPoExample;
import com.jackstraw.jack_base.rules.exception.BadRuleException;
import com.jackstraw.jack_base.rules.service.RelationRgrService;
import com.jackstraw.jack_base.rules.service.RelationSargService;
import com.jackstraw.jack_base.rules.service.RuleGroupService;
import com.jackstraw.jack_base.rules.service.RuleService;
import com.jackstraw.jack_base.util.CollectionUtil;
import com.jackstraw.jack_base.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 规则组表  service实现类
 *
 * @author zhaozhao 945514650@qq.com
 * @since version:1.0 generatorDate:2022-12-04 14:28:29
 */
@Slf4j
@DataSourceNameCut(dataSourceName = "dataBaseName1", dataSourceTypeEnum = DataSourceTypeEnum.database)
public class RuleGroupServiceImpl
        extends MyBatisServiceImpl<RuleGroupDao, RuleGroupPo, RuleGroupBo, RuleGroupKeyPo<RuleGroupPo>, RuleGroupPoExample>
        implements RuleGroupService {

    @Autowired
    private RuleGroupMapstruct ruleGroupMapstruct;

    @Autowired
    private RuleService ruluService;

    @Autowired
    private RelationSargService relationSargService;

    @Autowired
    private RelationRgrService relationRgrService;

    @Override
    protected RuleGroupPoExample pe(Map<String, Object> params) {
        RuleGroupPoExample pe = super.pe(params);
        //默认查询主键
        pe.addKey(params);
        return pe;
    }

    @Override
    public List<RuleGroupBo> queryAllRelationGroupsById(Long sceneActuatorId) {
        List<RelationSargBo> relationSargBos = relationSargService.queryAllBySceneId(sceneActuatorId);
        if (CollectionUtil.isEmpty(relationSargBos)) {
            log.warn("通过场景ID[{}]没有找到对应的规则组关系", sceneActuatorId);
            throw new BadRuleException(ResultEnum.SCENE_NO_FIND_RULES_GROUP_RELATION);
        }
        List<RuleGroupBo> ruleGroupBos = relationSargBos.stream()
                .collect(Collectors.toSet()).parallelStream()
                .map(relationSargBo -> {
                    RuleGroupBo ruleGroupBo = this.queryOneAll(relationSargBo.getRuleGroupId());
                    if (ObjectUtil.ObjectUtilByLang3.isNotEmpty(relationSargBo)) {
                        ruleGroupBo.setSort(relationSargBo.getSort());
                    }
                    return ruleGroupBo;
                })
                .filter(ruleGroupBo -> ObjectUtil.ObjectUtilByLang3.isNotEmpty(ruleGroupBo))
                .sorted(Comparator.comparing(RuleGroupBo::getSort))
                .collect(Collectors.toList());
        return ruleGroupBos;
    }

    @Override
    public RuleGroupBo queryOne(Long ruleGroupId) {
        RuleGroupKeyPo ruleGroupKeyPo = new RuleGroupKeyPo<>();
        ruleGroupKeyPo.setRuleGroupId(ruleGroupId);
        RuleGroupPo ruleGroupPo = this.getDao().selectByPrimaryKey(ruleGroupKeyPo);
        if (ObjectUtil.ObjectUtilByLang3.isEmpty(ruleGroupPo)) {
            throw new BadRuleException(ResultEnum.RULE_GROUP_DATA_NO_FIND_BY_DATABASE);
        }
        if (!Objects.equals(1, ruleGroupPo.getIsValid())) {
            throw new BadRuleException(ResultEnum.RULE_GROUP_DATA_LOSE_EFFICACY);
        }
        RuleGroupBo ruleGroupBo = ruleGroupMapstruct.bo(ruleGroupPo);
        return ruleGroupBo;
    }

    @Override
    public RuleGroupBo queryOneAll(Long ruleGroupId) {
        RuleGroupBo ruleGroupBo = this.queryOne(ruleGroupId);
        try {
            List<RuleBo> ruleBos = ruluService.getAllByRuleGroupId(ruleGroupId);
            ruleGroupBo.setRuleBos(ruleBos);
        } catch (BadRuleException badRuleException) {
            if (BadRuleException.errorCode(ResultEnum.RULE_GROUP_NO_FIND_RULES_RELATION.getCode()).equals(badRuleException.getErrorCode())) {
                return null;
            }
            if (BadRuleException.errorCode(ResultEnum.RULE_GROUP_NO_FIND_RULES.getCode()).equals(badRuleException.getErrorCode())) {
                return null;
            }
        }
        return ruleGroupBo;
    }

    @Override
    public Integer queryGroupVersion(Long ruleGroupId) {
        try {
            RuleGroupBo ruleGroupBo = this.queryOne(ruleGroupId);
            return ruleGroupBo.getVersion();
        } catch (BadRuleException badRuleException) {
            if (BadRuleException.errorCode(ResultEnum.RULE_GROUP_DATA_NO_FIND_BY_DATABASE.getCode()).equals(badRuleException.getErrorCode())) {
                return -1;
            }
            if (BadRuleException.errorCode(ResultEnum.RULE_GROUP_DATA_LOSE_EFFICACY.getCode()).equals(badRuleException.getErrorCode())) {
                return -2;
            }
        }
        return 0;
    }
}
